/**
 * @description 遍历模板AST，递归地访问到所有的节点
 * @param {*} ast 模板AST
 */
export function traverseNode(ast, context) {
  /* 当前节点， ast 本身就是Root节点 */
  context.currentNode = ast;

  /* 遍历转换子节点的退出阶段（完成后）执行的回调函数列表 */
  const exitFns = [];

  const transforms = context.transforms;

  /* 对当前节点进行转换 */
  for (let index = 0; index < transforms.length; index++) {
    const transform = transforms[index];
    const exitFn = transform(context.currentNode, context);

    /* 添加到退出阶段时执行的回调函数列表 */
    if (exitFn) {
      exitFns.push(exitFn);
    }

    /* 如果转换后，当前节点被删除不存在了， 那也没有必要继续处理子节点了*/
    if (!context.currentNode) return;
  }

  /* 子节点列表 */
  const children = context.currentNode.children;
  /* 判断是否有子节点 */
  if (children && children.length) {
    /* 递归获取子节点，然后对子节点进行转换 */
    for (let i = 0; i < children.length; i++) {
      context.parent = context.currentNode;
      context.currentIndex = i;
      const child = children[i];
      traverseNode(child, context);
    }
  }

  /* 执行退出遍历子节点阶段的回调函数列表中的回调函数 */
  let i = exitFns.length;
  while (i--) {
    exitFns[i]();
  }
}

